using System;
using System.IO;
using System.Text;
using View.Common;
namespace View.Replay.Application
{
    public enum VarType
    {
        Undefined,
        Int,
        Float,
        Bool,
        String,
        Binary,
        Long = 7,
        DateTime,
        Object = 6
    }
    public enum ParameterRight
    {
        User = 1,
        ProjectDebuger,
        Developer = 4
    }

	public struct Variable
	{
		public static readonly Variable Invalid = default(Variable);
		private object objVal;
		private object defValue;
		public VarType VarType
		{
			get;
			private set;
		}
		public object Value
		{
			get
			{
				return this.objVal;
			}
		}
		private int iVal
		{
			get
			{
				return (int)this.objVal;
			}
			set
			{
				this.objVal = value;
			}
		}
		private long lVal
		{
			get
			{
				return (long)this.objVal;
			}
			set
			{
				this.objVal = value;
			}
		}
		private float fVal
		{
			get
			{
				return (float)this.objVal;
			}
			set
			{
				this.objVal = value;
			}
		}
		private string strVal
		{
			get
			{
				return (string)this.objVal;
			}
			set
			{
				this.objVal = value;
			}
		}
		private byte[] binBuf
		{
			get
			{
				return (byte[])this.objVal;
			}
			set
			{
				this.objVal = value;
			}
		}
		private bool bVal
		{
			get
			{
				return (bool)this.objVal;
			}
			set
			{
				this.objVal = value;
			}
		}
		private DateTime dtVal
		{
			get
			{
				return (DateTime)this.objVal;
			}
			set
			{
				this.objVal = value;
			}
		}
		public Variable(int val)
		{
			this = default(Variable);
			this.objVal = val;
			this.VarType = VarType.Int;
		}
		public Variable(long val)
		{
			this = default(Variable);
			this.objVal = val;
			this.VarType = VarType.Long;
		}
		public Variable(float val)
		{
			this = default(Variable);
			this.objVal = val;
			this.VarType = VarType.Float;
		}
		public Variable(bool val)
		{
			this = default(Variable);
			this.objVal = val;
			this.VarType = VarType.Bool;
		}
		public Variable(string val)
		{
			this = default(Variable);
			this.objVal = val;
			this.VarType = VarType.String;
		}
		public Variable(byte[] buf)
		{
			this = default(Variable);
			this.objVal = buf;
			this.VarType = VarType.Binary;
		}
		public Variable(DateTime val)
		{
			this = default(Variable);
			this.objVal = val;
			this.VarType = VarType.DateTime;
		}
		public Variable(object obj)
		{
			this = default(Variable);
			this.objVal = obj;
			if (obj != null)
			{
				if (obj is string)
				{
					this.VarType = VarType.String;
				}
				else
				{
					if (obj is int)
					{
						this.VarType = VarType.Int;
					}
					else
					{
						if (obj is float)
						{
							this.VarType = VarType.Float;
						}
						else
						{
							if (obj is bool)
							{
								this.VarType = VarType.Bool;
							}
							else
							{
								if (obj is byte[])
								{
									this.VarType = VarType.Binary;
								}
								else
								{
									if (obj is long)
									{
										this.VarType = VarType.Long;
									}
									else
									{
										if (obj is DateTime)
										{
											this.VarType = VarType.DateTime;
										}
										else
										{
											if (obj is Variable)
											{
												Variable variable = (Variable)obj;
												this.objVal = variable.Value;
												this.VarType = variable.VarType;
											}
											else
											{
												this.VarType = VarType.Object;
											}
										}
									}
								}
							}
						}
					}
				}
			}
			else
			{
				this.VarType = VarType.Object;
			}
		}
		public void SetDefValue(object obj)
		{
			this.defValue = obj;
		}
		public static implicit operator Variable(int val)
		{
			return new Variable(val);
		}
		public static implicit operator Variable(uint val)
		{
			return new Variable((int)val);
		}
		public static implicit operator Variable(short val)
		{
			return new Variable((int)val);
		}
		public static implicit operator Variable(ushort val)
		{
			return new Variable((int)val);
		}
		public static implicit operator Variable(byte val)
		{
			return new Variable((int)val);
		}
		public static implicit operator Variable(long val)
		{
			return new Variable(val);
		}
		public static implicit operator Variable(ulong val)
		{
			return new Variable((long)val);
		}
		public static implicit operator Variable(float val)
		{
			return new Variable(val);
		}
		public static implicit operator Variable(bool val)
		{
			return new Variable(val);
		}
		public static implicit operator Variable(string val)
		{
			return new Variable(val);
		}
		public static implicit operator Variable(byte[] byt)
		{
			return new Variable(byt);
		}
		public static implicit operator Variable(DateTime t)
		{
			return new Variable(t);
		}
		public static implicit operator int(Variable val)
		{
			return val.ToInt();
		}
		public static implicit operator uint(Variable val)
		{
			return (uint)val.ToInt();
		}
		public static implicit operator long(Variable val)
		{
			return val.ToLong();
		}
		public static implicit operator float(Variable val)
		{
			return val.ToFloat();
		}
		public static implicit operator bool(Variable val)
		{
			return val.ToBool();
		}
		public static implicit operator string(Variable val)
		{
			return val.ToVaString();
		}
		public static implicit operator DateTime(Variable val)
		{
			return val.ToDateTime();
		}
		public static implicit operator byte[](Variable val)
		{
			return val.ToBytes();
		}
		private int ToInt()
		{
			int num = 0;
			if (this.defValue != null && this.defValue is int)
			{
				num = (int)this.defValue;
			}
			int result;
			if (this.Value == null)
			{
				result = num;
			}
			else
			{
				switch (this.VarType)
				{
				case VarType.Bool:
					result = (this.bVal ? 1 : num);
					break;
				case VarType.String:
                    result = UtilityFunc.ToInt(this.strVal, num);
					break;
				default:
					result = Convert.ToInt32(this.Value);
					break;
				}
			}
			return result;
		}
		private long ToLong()
		{
			long num = 0L;
			if (this.defValue != null && this.defValue is long)
			{
				num = (long)this.defValue;
			}
			long result;
			if (this.Value == null)
			{
				result = num;
			}
			else
			{
				switch (this.VarType)
				{
				case VarType.Bool:
					result = (this.bVal ? 1L : num);
					break;
				case VarType.String:
                    result = UtilityFunc.ToLong(this.strVal, num);
					break;
				default:
					result = Convert.ToInt64(this.Value);
					break;
				}
			}
			return result;
		}
		private float ToFloat()
		{
			float num = 0f;
			if (this.defValue != null && this.defValue is float)
			{
				num = (float)this.defValue;
			}
			float result;
			if (this.Value == null)
			{
				result = num;
			}
			else
			{
				switch (this.VarType)
				{
				case VarType.Bool:
					result = (this.bVal ? 1f : num);
					break;
				case VarType.String:
                    result = UtilityFunc.ToFloat(this.strVal, num);
					break;
				default:
					result = Convert.ToSingle(this.Value);
					break;
				}
			}
			return result;
		}
		private bool ToBool()
		{
			bool flag = false;
			if (this.defValue != null && this.defValue is bool)
			{
				flag = (bool)this.defValue;
			}
			bool result;
			if (this.Value == null)
			{
				result = flag;
			}
			else
			{
				switch (this.VarType)
				{
				case VarType.Int:
					result = (this.iVal != 0);
					return result;
				case VarType.Float:
                    result = (this.fVal != 0f && UtilityFunc.FloatIsNaN(this.fVal));
					return result;
				case VarType.Bool:
					result = this.bVal;
					return result;
				case VarType.String:
					result = (this.strVal == "1" || this.strVal == "是" || this.strVal.ToUpper() == "TRUE");
					return result;
				case VarType.Object:
					result = this.bVal;
					return result;
				}
				result = false;
			}
			return result;
		}


		private string ToVaString()
		{
			string text = "";
			if (this.defValue != null && this.defValue is string)
			{
				text = (string)this.defValue;
			}
			string result;
			if (this.Value == null)
			{
				result = text;
			}
			else
			{
				result = this.Value.ToString();
			}
			return result;
		}
		private DateTime ToDateTime()
		{
			DateTime dateTime = DateTime.MinValue;
			if (this.defValue != null && this.defValue is DateTime)
			{
				dateTime = (DateTime)this.defValue;
			}
			DateTime result;
			if (this.Value == null)
			{
				result = dateTime;
			}
			else
			{
				if (this.Value is DateTime)
				{
					result = this.dtVal;
				}
				else
				{
					result = dateTime;
				}
			}
			return result;
		}
		private byte[] ToBytes()
		{
			byte[] array = null;
			if (this.defValue != null && this.defValue is byte[])
			{
				array = (byte[])this.defValue;
			}
			byte[] result;
			if (this.Value == null)
			{
				result = array;
			}
			else
			{
				switch (this.VarType)
				{
				case VarType.Int:
					result = BitConverter.GetBytes(this.iVal);
					return result;
				case VarType.Float:
					result = BitConverter.GetBytes(this.fVal);
					return result;
				case VarType.Bool:
					result = BitConverter.GetBytes(this.bVal);
					return result;
				case VarType.String:
					result = Encoding.Unicode.GetBytes(this.strVal);
					return result;
				case VarType.Binary:
					result = this.binBuf;
					return result;
				case VarType.DateTime:
					result = BitConverter.GetBytes(this.dtVal.Ticks);
					return result;
				}
				result = null;
			}
			return result;
		}
		public static bool operator ==(Variable v1, Variable v2)
		{
			bool result;
			if (v1.VarType == v2.VarType)
			{
				result = object.Equals(v1.objVal, v2.objVal);
			}
			else
			{
				result = v1.Equals(v2);
			}
			return result;
		}
		public static bool operator !=(Variable v1, Variable v2)
		{
			bool result;
			if (v1.VarType == v2.VarType)
			{
				result = !object.Equals(v1.objVal, v2.objVal);
			}
			else
			{
				result = !v1.Equals(v2);
			}
			return result;
		}
		public override bool Equals(object obj)
		{
			bool result;
			if (obj == null)
			{
				result = false;
			}
			else
			{
				if (obj.GetType() == typeof(Variable))
				{
					result = (this.objVal == ((Variable)obj).objVal);
				}
				else
				{
					result = (obj == this.objVal);
				}
			}
			return result;
		}
		public override int GetHashCode()
		{
			return base.GetHashCode();
		}
		public static Variable operator +(Variable a, Variable b)
		{
			Variable result;
			switch (a.VarType)
			{
			case VarType.Int:
				if (b.VarType == VarType.Float)
				{
					result = (float)a.iVal + b.fVal;
					return result;
				}
				if (b.VarType == VarType.Long)
				{
					result = (long)a.iVal + b.lVal;
					return result;
				}
				result = a.iVal + b;
				return result;
			case VarType.Float:
				result = a.fVal + b;
				return result;
			case VarType.Bool:
				result = (a.bVal | b);
				return result;
			case VarType.String:
				result = a.strVal + b;
				return result;
			case VarType.DateTime:
				if (b.VarType == VarType.Int)
				{
					if (a.dtVal != DateTime.MinValue && a.dtVal != DateTime.MaxValue)
					{
						result = a.dtVal.AddSeconds((double)b.iVal);
						return result;
					}
				}
				if (b.VarType == VarType.Float)
				{
					if (a.dtVal != DateTime.MinValue && a.dtVal != DateTime.MaxValue)
					{
						result = a.dtVal.AddSeconds((double)b.fVal);
						return result;
					}
				}
				result = a;
				return result;
			}
			result = a;
			return result;
		}
		public static Variable operator -(Variable a, Variable b)
		{
			VarType varType = a.VarType;
			Variable result;
			switch (varType)
			{
			case VarType.Int:
				if (b.VarType == VarType.Float)
				{
					result = (float)a.iVal - b.fVal;
				}
				else
				{
					result = a.iVal - b;
				}
				break;
			case VarType.Float:
				result = a.fVal - b;
				break;
			default:
				if (varType != VarType.DateTime)
				{
					result = a;
				}
				else
				{
					if (b.VarType == VarType.Int)
					{
						if (a.dtVal != DateTime.MinValue && a.dtVal != DateTime.MaxValue)
						{
							result = a.dtVal.AddSeconds((double)(-(double)b.iVal));
							break;
						}
					}
					if (b.VarType == VarType.Float)
					{
						if (a.dtVal != DateTime.MinValue && a.dtVal != DateTime.MaxValue)
						{
							result = a.dtVal.AddSeconds((double)(-(double)b.fVal));
							break;
						}
					}
					result = a;
				}
				break;
			}
			return result;
		}
		public static Variable operator *(Variable a, Variable b)
		{
			Variable result;
			switch (a.VarType)
			{
			case VarType.Int:
				if (b.VarType == VarType.Float)
				{
					result = (float)a.iVal * b.fVal;
				}
				else
				{
					result = a.iVal * b;
				}
				break;
			case VarType.Float:
				result = a.fVal * b;
				break;
			case VarType.Bool:
				result = (a.bVal && b);
				break;
			default:
				result = a;
				break;
			}
			return result;
		}
		public static Variable operator /(Variable a, Variable b)
		{
			Variable result;
			switch (a.VarType)
			{
			case VarType.Int:
				result = (float)a.iVal / b;
				break;
			case VarType.Float:
				result = a.fVal / b;
				break;
			default:
				result = a;
				break;
			}
			return result;
		}
		public override string ToString()
		{
			string result;
			if (this.Value == null)
			{
				result = "";
			}
			else
			{
				switch (this.VarType)
				{
				case VarType.Int:
					result = "Int:" + this.iVal.ToString();
					return result;
				case VarType.Float:
					result = "Float:" + this.fVal.ToString("f3");
					return result;
				case VarType.Bool:
					result = "Bool:" + (this.bVal ? "True" : "False");
					return result;
				case VarType.String:
					result = this.strVal;
					return result;
				case VarType.Binary:
                    result = "Binary:" + UtilityFunc.BinaryToString(this.binBuf, 2147483647);
					return result;
				case VarType.Long:
					result = "Long:" + this.objVal.ToString();
					return result;
				case VarType.DateTime:
                    result = "DateTime:" + UtilityFunc.GetTimeString((DateTime)this.Value);
					return result;
				}
				result = this.objVal.ToString();
			}
			return result;
		}
		private static VarType GetVarType(string typeName)
		{
			VarType result;
			switch (typeName)
			{
			case "Int":
				result = VarType.Int;
				return result;
			case "Long":
				result = VarType.Long;
				return result;
			case "Float":
				result = VarType.Float;
				return result;
			case "Bool":
				result = VarType.Bool;
				return result;
			case "String":
				result = VarType.String;
				return result;
			case "Binary":
				result = VarType.Binary;
				return result;
			case "DateTime":
				result = VarType.DateTime;
				return result;
			}
			result = VarType.Undefined;
			return result;
		}
		public static Variable Parse(string str)
		{
			Variable result;
			if (!string.IsNullOrEmpty(str))
			{
				int num = str.IndexOf(':');
				if (num <= 0)
				{
					result = new Variable(str);
				}
				else
				{
					VarType varType = Variable.GetVarType(str.Substring(0, num));
					string text = str.Substring(num + 1);
					result = Variable.Parse(str, varType);
				}
			}
			else
			{
				result = Variable.Invalid;
			}
			return result;
		}
		public static Variable Parse(string str, VarType type)
		{
			Variable result;
			if (!string.IsNullOrEmpty(str))
			{
				int num = str.IndexOf(':');
				string text = (num <= 0) ? str : str.Substring(num + 1);
				if (num >= 0)
				{
					type = Variable.GetVarType(str.Substring(0, num));
				}
				switch (type)
				{
				case VarType.Int:
                        result = UtilityFunc.ToInt(text, 0);
					return result;
				case VarType.Float:
                    result = UtilityFunc.ToFloat(text, 0f);
					return result;
				case VarType.Bool:
					text = text.ToUpper();
					result = ("是".Equals(text) || "TRUE".Equals(text) || "YES".Equals(text) || "OK".Equals(text) || "1".Equals(text));
					return result;
				case VarType.String:
					result = new Variable(text);
					return result;
				case VarType.Binary:
                    result = new Variable(UtilityFunc.BinaryFromString(text));
					return result;
				case VarType.Long:
                    result = UtilityFunc.ToLong(text, 0L);
					return result;
				case VarType.DateTime:
                    result = new Variable(UtilityFunc.ToDateTime(text));
					return result;
				}
				result = new Variable(str);
			}
			else
			{
				result = Variable.Invalid;
			}
			return result;
		}
		public int GetValByteLen()
		{
			int result;
			switch (this.VarType)
			{
			case VarType.Int:
			case VarType.Float:
				result = 4;
				return result;
			case VarType.Bool:
				result = 1;
				return result;
			case VarType.String:
				result = ((this.strVal == null) ? 4 : (4 + this.strVal.Length * 2));
				return result;
			case VarType.Binary:
				result = 4 + ((this.binBuf == null) ? 0 : this.binBuf.Length);
				return result;
			case VarType.Long:
				result = 8;
				return result;
			case VarType.DateTime:
				result = 8;
				return result;
			}
			result = 0;
			return result;
		}
		public int WriteValBytes(BinaryWriter bw)
		{
			int result;
			switch (this.VarType)
			{
			case VarType.Int:
				bw.Write(this.iVal);
				result = 4;
				return result;
			case VarType.Float:
				bw.Write(this.fVal);
				result = 4;
				return result;
			case VarType.Bool:
				bw.Write(this.bVal ? 1 : 0);
				result = 1;
				return result;
			case VarType.String:
				if (string.IsNullOrEmpty(this.strVal))
				{
					bw.Write(0);
					result = 0;
					return result;
				}
				bw.Write(this.strVal.Length);
				bw.Write(this.strVal.ToCharArray());
				result = 4 + this.strVal.Length * 2;
				return result;
			case VarType.Binary:
				if (this.binBuf == null)
				{
					bw.Write(0);
					result = 4;
					return result;
				}
				bw.Write(this.binBuf.Length);
				bw.Write(this.binBuf);
				result = 4 + this.binBuf.Length;
				return result;
			case VarType.Long:
				bw.Write((long)this.objVal);
				result = 8;
				return result;
			case VarType.DateTime:
				bw.Write(this.dtVal.Ticks);
				result = 8;
				return result;
			}
			result = 0;
			return result;
		}
		public static Variable ReadValBytes(BinaryReader br, VarType keyType)
		{
			Variable result;
			switch (keyType)
			{
			case VarType.Int:
				result = br.ReadInt32();
				return result;
			case VarType.Float:
				result = br.ReadSingle();
				return result;
			case VarType.Bool:
				result = (br.ReadByte() == 1);
				return result;
			case VarType.String:
			{
				int num = br.ReadInt32();
				result = new string(br.ReadChars(num));
				return result;
			}
			case VarType.Binary:
			{
				int num = br.ReadInt32();
				if (num > 0)
				{
					result = br.ReadBytes(num);
					return result;
				}
				result = new byte[0];
				return result;
			}
			case VarType.Long:
				result = br.ReadInt64();
				return result;
			case VarType.DateTime:
				result = new DateTime(br.ReadInt64());
				return result;
			}
			result = 0;
			return result;
		}
	}
}
